package dai.samples.batch.config;

import org.springframework.batch.core.configuration.ListableJobLocator;
import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.support.MapJobRegistry;
import org.springframework.batch.core.converter.JobParametersConverter;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.explore.support.JobExplorerFactoryBean;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
import org.springframework.batch.core.launch.support.SimpleJobOperator;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

/**
 * @author daify
 * @date 2020-11-03
 */
@Configuration
public class BatchConfig extends DefaultBatchConfigurer {

    public static final String PATH = "target/test-outputs/";

    @Autowired
    private DataSource dataSource;


    /**
     * 初始化资源型事务控制
     * @return
     */
    @Bean
    JpaTransactionManager transactionManager() {
        return new JpaTransactionManager();
    }

    /**
     * 初始化资源型事务控制
     * @return
     */
    /*@Bean
    PlatformTransactionManager transactionManager() {
        return new ResourcelessTransactionManager();
    }*/

    /**
     * 任务持久化 使用JDBC
     * @return
     * @throws Exception
     */
    @Bean
    protected JobRepository jobRepository() throws Exception {
        setDataSource(dataSource);
        JobRepository jobRepository = createJobRepository();
        return jobRepository;
    }

    /**
     * 任务持久化 使用内存的时候JDBC设置
     * @return
     * @throws Exception
     */
    /*@Override
    public void setDataSource(DataSource dataSource) {

    }*/

    /**
     * 任务持久化 使用内存
     * @return
     * @throws Exception
     */
    /*@Bean
    protected JobRepository jobRepository() throws Exception {
        MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean();
        factory.setTransactionManager(transactionManager());
        return factory.getObject();
    }*/

    @Bean
    JobBuilderFactory jobBuilderFactory() throws Exception {
        return new JobBuilderFactory(jobRepository());
    }

    @Bean
    StepBuilderFactory stepBuilderFactory() throws Exception {
        return new StepBuilderFactory(jobRepository(),transactionManager());
    }

    /**
     * 任务启动器
     * @return
     * @throws Exception
     */
    @Bean
    public JobLauncher jobLauncher() throws Exception {
        SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
        simpleJobLauncher.setJobRepository(jobRepository());
        return simpleJobLauncher;
    }

    @Bean
    JobExplorer jobExplorer() throws Exception {
        JobExplorerFactoryBean jobExplorerFactoryBean = new JobExplorerFactoryBean();
        jobExplorerFactoryBean.setDataSource(dataSource);
        jobExplorerFactoryBean.afterPropertiesSet();
        return jobExplorerFactoryBean.getObject();
    }

    @Bean
    public ListableJobLocator listableJobLocator() {
        return new MapJobRegistry();
    }


    @Bean
    public SimpleJobOperator jobOperator(@Autowired ObjectProvider<JobParametersConverter> jobParametersConverter) {
        SimpleJobOperator factory = new SimpleJobOperator();
        factory.setJobExplorer(getJobExplorer());
        factory.setJobLauncher(getJobLauncher());
        factory.setJobRegistry(listableJobLocator());
        factory.setJobRepository(getJobRepository());
        jobParametersConverter.ifAvailable(factory::setJobParametersConverter);
        return factory;
    }


}
